<html>
    <head>
        <title>循环引用</title>
    </head>
    <body>
        <script>
            // 循环引用
                    // 一、递归组件
                                // 组件时可以在它们自己的模板中"调用自身"的。  不过它们只能通过 name 选项来做这件事。
                                        name: 'unique-name-of-my-component'

                                /*
                                    当你使用 Vue.component 全局注册组件时，这个全局的ID会自动设置为该组件的　name 选项。
                                */
                                        Vue.component('unique-name-of-my-component',{
                                            // ... 
                                        });

                                // 稍有不慎，递归组件就可能导致无限循环：
                                        name: 'stack-overflow',
                                        template:'<div><stack-overflow></stack-overflow></div>'

                                /*
                                   类似上述的组件将会导致"max stack size exceeded" 错误，
                                   所以请确保递归调用时条件性的  (例如，使用一个最终得到false 的 v-if)
                                */

                    
                    // 二、组件间的循环引用
                                /*
                                    假设你需要构建一个文件目录树，像访达或资源管理器那样的。
                                    你可能有一个<tree-folder>组件，模板是这样的：

                                        <p>
                                            <span>{{folder.name}}</span>
                                            <tree-folder-contents: children="floder.children">
                                        </p>

                                    还有一个 <tree-folder-contents>组件，模板是这样的:
                                        <ul>
                                            <li v-for="child in children">
                                                <tree-folder v-if="child.children" :folder="child"/>
                                                <span v-else>{{child.name}}</span>
                                            </li>
                                        </ul>
                                    
                                    当你仔细观察的时候，你会发现这些组件在渲染树中互为对方的后代和祖先-----一个悖论！！
                                    当通过 Vue.component 全局注册组件的时候，这个悖论会被"自动解开"。如果你是这样做的，那么你可以跳过这里。

                                    然而，如果你使用一个模块系统依赖/导入组件，例如通过 webpack 或 Browerify ，你会遇到一个错误：

                                            "Failed to mount component: template or render function not defined."

                                    为了解释这里发生了什么，我们先把两个组件称为A 和 B 。
                                    模块系统发现它需要A，但是首先A依赖于B，但是B又依赖于A，如此往复出现了"循环依赖"，不知道如何不经过其中一个组件就能完全解析另一个组件。
                                    为了解决这个问题，我们需要给模块系统一个点，在这个点上"A 反正是需要B的，但是我们不需要先解析B，就能解析A"。
                                */

                                /*
                                    在我们的例子中，把<tree-folder>组件设为了那个"点"。
                                    我们知道那个产生悖论的子组件是 <tree-folder-contents>组件，


                                    所以我们会等到生命周期钩子"beforeCreate"时才去注册 <tree-folder-contents>组件:
                                */
                                        beforeCreate:function(){
                                            this.$options.components.TreeFolderContents = require('./tree-folder-contents.vue').default
                                        }

                                // 或者，在本地注册组件的时候，你可以使用 webpack 的异步 import 功能：
                                        components:{
                                            TreeFolderContents:()=>import('./tree-folder-contents.vue')
                                        }

                                // 这样问题就解决了！！！！
        </script>
    </body>
</html>   